1. Authoring Webpack Library

Home

1. Authoring Webpack Library

Follow Webpack doc: authoring webpack library to configure webpack.

npm init -y
npm install --save-dev lodash
webpack

Key point

In webpack.config.js:

  output: {
    filename: 'tutorialib.js',
    path: path.resolve(__dirname, 'dist'),
    library: 'tutorialib',
    libraryTarget: 'umd'
  },

Download Source

Trouble: externals doesn't work

TypeError: lodash__WEBPACK_IMPORTED_MODULE_0___default.a is undefined

There are a lot of similar reports, like the question at stackoverflow, not resolved (bug?)

2. Thinking in Vue Component

Vue is born with the object of designing as components.

This section we will implement a popping up window, which is dynamically loading data, interacted with user events.

The popup component is modified from the source of a tutorial by Neo Ighodaro [4]. The source is avialable at github.

The component is bundled into module named 'prevComp', which is exported from source file PreComp.js:

		import Vue from 'vue'
		import UserPop from './UserPop.vue'
		import UserPopImage from './UserPopImage.vue'

		const prevComp =  {
		    install: function (Vue, options) {
		        Vue.component('user-pop', UserPop)
		        Vue.component('user-pop-image', UserPopImage)
		    }
		}

		export default prevComp;

The module is used in test.js, wich serves as an example of how to use the vue component we exported early.

The exported bundle (dist/prev.component.js) is included in test.html, as an old javascript fashion for showing the module concept clearly.

<script src='./dist/prev.component.js' type='text/javascript'></script>

The in the test.html, a basic Vue component is created as a container of the built component.

	<comp-item
		v-for="msg in messages"
		v-bind:item="msg"
		v-bind:key="msg.user.name">
	</comp-item>

The 'comp-item' template is the caller of our exported vue module 'prevComp'. In test.js:

	Vue.component('comp-item', {
	    props: ['item'],
	    template: '<user-pop :user="item.user" :main="item.user.name"></user-pop>'
	});

In the code above, component <user-pop> is the component name registered in PrevComp.js.

prevComp is been actually installed by test.js:

prevComp.default.install(Vue);

The source project (with test example) is provided here.

To understand the source, it's highly recommended to thoroughly read through referenc 1, 2 and 3.

3. Import Plugins from Vue.js Examples[5] (with source)

3.1 Setting up Project

Ass we are planning using component source, we directly downloaded DataTable.vue file.

npm install --save-dev vue vue-loader vue-template-compiler style-loader css-loader axios

3.2 Using DataTable[6] from Vue.js Examples

Download and use it int test.js

    import Vue from 'vue';
    import DataTable from './components/DataTable.vue';

    Vue.component({DataTable});

    window.onload = function init() {
        console.log(this);
        new Vue({
            render: h => h(DataTable)
        }).$mount('#app')
    }

If you have trouble to understand how the DataTable render function is working, you are suggested stoping here and reading through reference [7], [8], [9], [10], [11], - not that much as first look.

Then you can figure out how the final resutls can managed working - resolve error of referencing css and fonts resources.


The project milestone (source project step 1) which can be downloaded here shows the process of how to resolve css and font problems.

Also the Demo Page is here.

4. JS OOP with Suport from Webpack

Prjoect Source

Sample Project Screenshot:

webpack.config.js

        var path = require('path')
        var webpack = require('webpack')

        module.exports = {
          mode: "development",
          devtool: 'source-map',

          entry: './lib/TestClass.js',

          output: {
            filename: "test-class.min.js", // string

            path: path.resolve(__dirname, 'dist'),
            publicPath: "./dist/", // string

            library: 'Shapes',
            libraryTarget: 'umd'
          },
        }

Demo Page

The source file (TestClass.js) can be downloaded here shows some OOP conceptions:

OOP Key Points

concept code snipet remarks
class and subclass - inheritance TestClass.js
            class Shape {
                ...
            }

            class Rectangle extends Shape {
                ...
            }
typeof Shape === 'function'
See [12]
constructor TestClass.js
            class Rectangle extends Shape {
              constructor(height, width) {
            	super('Rectangle');
                this.height = height;
                this.width = width;
              };
              ...
            }
[12]
abstract class and
constructor or methods overriden
TestClass.js
            class Shape {
              constructor (tn) {
                // abstract class constructor can't been called
                if (this.constructor === Shape) {
                    throw new Error('Cannot instantaciate abstract class Shape');
                }
              }

              /** Getter */
              get area() {
                // call overriden method - polymorphism
                return this.calcArea();
              }

              /**Overriden method */
              calcArea () {
                throw new Error('Cannot call abstract method')
              };
            }

            /**Concreate class */
            class Rectangle extends Shape {
              constructor(height, width) {
                // super() won't throw Error because this.constructor === Rectangle
                super('Rectangle');
                ...
              };

              /**Overriding Method */
              calcArea() {
                return this.height * this.width;
              }
            }
Ideas comes from [13]
static methods and variables TestClass.js
            class Shape {
              static tname() { return Shape._tn; }
            }
using static method in test/index.html
            console.log(Shapes.Rectangle.tname());
See [14]
static methods and variables TestClass.js
            var Geometry = new class {
                constructor(n) {
                    this.name = n
                }

                log() {
                    console.log(this.name);
                }
            } ('App'); 
using static method in test/index.html
            Shapes.Geometry.log();
JS anonymous class is not a good practise, see [15]

5. Modify DataTable to Semantable

As DataTable doesn't very suitable for paging at server side, and even no pager, let's modify it to integrate a pager and load rows paged at server side, the Semantable.

Of cause, Semantable needing to access our semantic.jserv data servics.

The finished Semantable component looks like this.


Source and Simple Static Demo, or Basic Server Side Paging Demo.

Tip: Vue slot is a tool powerful for making vue components customerizable. The ENA Table from Vue.js Examples is a good example showing how to use slots to customerize vue components.

Code Snipet Explained

Function Source Remarks

To be continued ...

6. Modify Sidebar Menue to Dynamic Menu [17, 18]

project soure (zip)
README.md
Sidebar Menu Component

6.1 Static Menu

App using vue components (only with menu components avialable statically)
webpack.config.js
demo

6.2 Dynamic Menu

App using vue components (only the daynamic menu components avialable)
webpack.config.js
demo

7. Transpiling Tree [19] & Popping Modal Dialog

Tree Component
App using vue components (only with tree components avialable statically)
webpack.config.js
demo

In this project:

1. Using Tree with JSX

The component using JSX for replacing render function - for dynamic template

See tpl attribute in Tree.vue.

To compile with JSX, in webpack.config.js:

module: { rules: [
{test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", options: { plugins: ['transform-vue-jsx'] }},
...

For render function and JSX, see [20]

For toturial of using JSX with Vue.js, see [21]

2. Using Modal Dialog

This demo page also showing how to popping and recieving results of modal dialog, which is modified from VueJs exmaple.

For VueJS docs about modal dialog example, see [22].

		<button class=" tree-search-btn" type="button" @click="show('modal-1')">Show Modal1</button>
		<button class=" tree-search-btn" type="button" @click="show('modal-2')">Show Modal2</button>
		<modal ref="modal-1"><user-form slot='modal-form'/></modal>
		<modal ref="modal-2"/>
<script> const UserForm = { template: '...' } Vue.component('user-form', UserForm); </script>

Troubleshootings

Error Handling
            /usr/local/bin/nodejs/lib/node_modules/webpack-cli/bin/cli.js:235
                throw err;
                ^
            Error: Cannot find module 'webpack'
Setup NODE_PATH. In ubuntu:
export NODE_PATH=/usr/local/bin/nodejs/lib/node_modules/
            Error: Cannot find module '@babel/core'
             babel-loader@8 requires Babel 7.x (the package '@babel/core').
             If you'd like to use Babel 6.x ('babel-core'), you should install 'babel-loader@7'.
            
That's because new version of babel dependency.
sudo npm install -g @babel/core
npm link @babel/core
sudo npm install -g babel-loader
npm link babel-loader
See Answer by CounterFlame.
Firefox complain about source map
Don't use name variable in library name in webpack.config.js.
This will produce warning message:
output: { library: 'j[name]'; }
instead use this:
output: { library: 'jvue'; }

References

  1. Vue.js doc: Guid / Introduction # Composing with Components
  2. Webpack doc: Authoring Component
  3. Vue.js doc: Component Basics
  4. Neo Ighodaro, Bulding External Modules in VueJS
  5. Vue.js Examples
  6. Vue.js Basic Datatable Source Project @ github
  7. Introduction to Vue.js Render Functions
  8. Understanding Component Slots with Vue.js
  9. Vue.js Doc: Vue.js API
  10. Vue.js Doc: Render Functions & JSX
  11. Slots, Vue.js Doc: Render Functions & JSX
  12. MDN Documents: Class and MDN Web technology for developer > JavaScript > JavaScript reference
  13. Advanced JavaScript Class: Abstract Class & Method
  14. Web technology for developers > JavaScript JavaScript reference > Classes > static
  15. Discusion ablout anonymous class on StackOverFlow
  16. ENA Table, a vue slots example, one of VueJs Examples
  17. VueJs Examples: Sidebar Menu
  18. VueJs Doc: Routing
  19. Tree @ Github, Halower
  20. Vue Doc: Render Function and JSX
  21. Tutorial at DNZone: Using JSX
  22. Vue.js Doc: Modal Component Example